/**
 * Inject the embeded script into a page and set listeners to the 
 * localStorage value.
 */

(function(){
	/**
	 * Chrome listeners
	 */
	chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
		if (request.action == "testPage") {
			init();
			sendResponse({});
		}
	});
	
	function notifyBackgroundPage() {
		chrome.extension.sendRequest({setLibs: localStorage[localStorage_key]}, function(response) {
			//delete the storage key
			localStorage.removeItem(localStorage_key);
			
			//notify that test is done
			test_running = false;
		});
	}
	
	
	var localStorage_key = "LD",
	    test_running = false;
	
	/**
	 * 
	 * 
	 * 
	 * 
	 */
	function page_test() {
		var localStorageKey = "LD",
			oldStorageValue = localStorage[localStorageKey],
			libs_passed = {},
			libs = {
					"jQuery" : {
						icon : "jquery",
						test : function(win) {
							var jq = win.jQuery || win.$ || win.$jq || win.$j;
							if(jq && jq.fn && jq.fn.jquery) {
								return { version: jq.fn.jquery };
							} else {
								return false;
							}
						}
					},
					
					"jQuery UI" : {
						icon : "jquery-ui",
						test: function(win) {
							
							var jq = win.jQuery || win.$ || win.$jq || win.$j;
							if(jq && jq.fn && jq.fn.jquery && jq.ui) {

								var plugins = 'accordion,datepicker,dialog,draggable,droppable,progressbar,resizable,selectable,slider,menu,grid,tabs'.split(','), concat = [];
								for (var i=0; i < plugins.length; i++) { if(jq.ui[plugins[i]]) concat.push(plugins[i].substr(0,1).toUpperCase() + plugins[i].substr(1)); };
							
								return { version: jq.ui.version || undefined, details: concat.length ? 'Plugins used: '+concat.join(',') : '' };
							} else {
								return false;
							}
							
						}
					},
					
					"jQuery Mobile" : {
						icon : "jquery-mobile",
						test: function(win) {
							
							var jq = win.jQuery || win.$ || win.$jq || win.$j;
							if(jq && jq.fn && jq.fn.jquery && jq.mobile) {
								return { version: undefined };
							} else {
								return false;
							}
							
						}
					},
					
					"Dojo" : {
						icon : "dojo",
						test : function(win) {
							if(win.dojo || win.djConfig) {
								return win.dojo ? { 
									version: win.dojo.version.toString(), 
									details: 'Details: '+(win.dijit ? 'Uses Dijit' : 'none')
								} : {
									version: undefined
								};
							} else {
								return false;
							}
						}
					},
					
					"Prototype" : {
						icon : "prototype",
						test : function(win) {
							if(win.Prototype && win.Prototype.Version) {
								return { version: win.Prototype.Version };
							} else {
								return false;
							}
						}
					},
					
					"Scriptaculous" : {
						icon : "scriptaculous",
						test : function(win) {
							if(win.Scriptaculous && win.Scriptaculous.Version) {
								return { version: win.Scriptaculous.Version };
							} else {
								return false;
							}
						}
					},
					
					"MooTools" : {
						icon : "mootools",
						test : function(win) {
							if(win.MooTools && win.MooTools.version) {
								return { version: win.MooTools.version };
							} else {
								return false;
							}
						}
					},
					
					"YUI" : {
						icon : "yui",
						test : function(win) {
							if((win.YAHOO && win.YAHOO.VERSION) || (win.YUI && win.YUI.version)) {
								return { version: win.YAHOO.VERSION || win.YUI.version};
							} else {
								return false;
							}
						}
					},
					
					"Sencha" : {
						icon : "sencha",
						test : function(win) {
							if(win.Ext && win.Ext.version) {
								return { version: win.Ext.version };
							} else {
								return false;
							}
						}
					},
					
					"Modernizr" : {
						icon : "modernizr",
						test : function(win) {
							if(win.Modernizr) {
								return { version: win.Modernizr._version };
							}
							return false;
						}
					},

					"GWT" : {
						icon : "gwt",
						test : function(win) {
							return win.__gwt_scriptsLoaded ? {version: undefined } : false;
						}
					},
					
					"Spry JS" : {
						icon : "spry_js",
						test : function(win) {
							if(win.Spry) {
								return { version: undefined };
							} else {
								return false;
							}
						}
					},
					
					"Qooxdoo" : {
						icon : "qooxdoo",
						test : function(win) {
							if(win.qx && win.qx.Bootstrap) {
								return { version: undefined };
							} else {
								return false;
							}
						}
					},
					
					"base2.DOM" : {
						test : function(win) {
							if(win.base2 && win.base2.version) {
								return { version: win.base2.version };
							} else {
								return false;
							}
						}
					},
					
					"Closure" : {
						icon : "closure",
						test : function(win) {
							if(win.goog) {
								return { version: '2.0' };
							}
							return false;
						}
					},
					
					"Raphael" : {
						icon : "raphael",
						test : function(win) {
							if(win.Raphael) {
								return { version: win.Raphael.version };
							}
							return false;
						}
					},
					
					"Processing.js" : {
						icon : "processing",
						test : function(win) {
							if(win.Processing) {
								return { version: win.Processing.version };
							}
							return false;
						}
					},
					
					"Backbone.js" : {
						icon : "backbone",
						test : function(win) {
							if (win.Backbone) {
								return {version: win.Backbone.VERSION};
							}
							return false;
						}
					},
					
					"Underscore.js" : {
						test : function(win) {
							if (win._ && win._.VERSION && typeof win._.tap === 'function') {
								return {version: win._.VERSION};
							}
							return false;
						}
					},
					
					"Sammy.js" : {
						icon : "sammyjs",
						test : function(win) {
							if (win.Sammy && win.Sammy.VERSION) {
								return {version: win.Sammy.VERSION};
							}
							return false;
						}
					},
					
					"Rico" : {
						test : function(win) {
							if (win.Rico && win.Rico.Version) {
								return {version: win.Rico.Version};
							}
							return false;
						}
					},
					
					"MochiKit" : {
						icon : "mochikit",
						test : function(win) {
							if (win.MochiKit) {
								return {version: win.MochiKit.VERSION};	
							}
							return false;
						}
					},
					
					"gRaphael" : {
						icon : "gRaphael",
						test : function(win) {
							if (win.Raphael && win.Raphael.fn.g) {
								return {version: undefined};
							}
							return false;
						}
					},
					
					"Glow" : {
						icon : "glow",
						test : function(win) {
							if (win.gloader) {
								return {version: undefined};
							}
							else if (win.glow) {
								return {version: win.glow.VERSION};
							}
							else if (win.Glow) {
								return {version: win.Glow.version};
							}
							return false;
						}
					},
					
					"Socket.IO" : {
						test : function(win) {
							if (win.io) {
								return {version: win.io.version};
							}
							return false;
						}
					},
					
					"Mustache.js" : {
						icon : "mustache",
						test : function(win) {
							if (win.Mustache) {
								return {version: win.Mustache.version};
							}
							return false;
						}
					},
					
					"Fabric.js" : {
						test : function(win) {
							if (win.fabric) {
								return {version: win.fabric.version};
							}
							return false;
						}
					},
					
					"FuseJS" : {
						icon : "fuseJS",
						test : function(win) {
							if (win.fuse) {
								return {version: win.fuse.version};
							}
							return false;
						}
					},
					
					"Tween.js" : {
						test : function(win) {
							if (win.TWEEN) {
								return {version: undefined};
							}
							return false;
						}
					},
					
					"SproutCore" : {
						icon : "SproutCore",
						test : function(win) {
							if (win.SC) {
								return {version: undefined};
							}
							return false;
						}
					},
					
					"Zepto.js" : {
						icon : "Zeptojs",
						test : function(win) {
							if (win.Zepto && win.Zepto.fn) {
								return {version: undefined};
							}
							return false;
						}
					},
					
					"three.js" : {
						test : function(win) {
							if (win.THREE) {
								return {version: undefined};
							}
							return false;
						}
					},
					
					"OpenAjaxHub" : {
						test : function(win) {
							if(win.OpenAjax) {
								if (win.OpenAjax.hub && win.OpenAjax.hub.implVersion) {
									return { version: win.OpenAjax.hub.implVersion };
								} else {
									return { version: undefined };
								}
							}
							return false;
						}
					},
					
					"Lightstreamer" : {
						icon : "Lightstreamer",
						test : function(win) {
							if(win.Lightstreamer && win.Lightstreamer.version) {
								return { version: win.Lightstreamer.version };
							} else if (win.PushPage && win.NonVisualTable) {
								return { version: undefined };
							}
							return false;
						}
					},
					
					"Ally" : {
						icon : "Ally",
						test : function(win) {
							if (win.Ally && win.Ally.version) {
								return {version: win.Ally.version};
							}
							return false;
						}
					},
					
					"enhanceJS" : {
						icon : "enhancejs",
						test : function(win) {
							if (window.enhance && window.appendToggleLinks) {
								return {version: undefined};
							}
						}
					}
			};
		
		/**
		 * 
		 */
		function triggerStorageEvent() {
			var storageEvent = document.createEvent("StorageEvent");
			storageEvent.initStorageEvent("storage", false, false, "LD", oldStorageValue, localStorage[localStorageKey], null, null);
			document.body.dispatchEvent(storageEvent);
		}
		
		/**
		 * 
		 * 
		 */
		function perform_tests() {
			var lib, version, i = 0, stringify = "";
			
			for (lib in libs) {
				if (libs[lib].test && (version = libs[lib].test(window))) {
					libs_passed[lib] = {
							version : version.version
					};
					
					if (libs[lib].icon) {
						libs_passed[lib].icon = libs[lib].icon;
					}
				};
			};
			
			if (!JSON.stringify) {
				return;
			}
			stringify = JSON.stringify(libs_passed);
			
			localStorage.setItem(localStorageKey, stringify === "{}" ? "" : stringify);
			/**
			 * Trigger manually onstorage event as currently it is not 
			 * triggered in Chrome, it is not supported.
			 */
			if (localStorage["onstorage"] === undefined) {
				triggerStorageEvent();
			}
		}
		
		/**
		 * 
		 */
		function init() {
			perform_tests();
		}
		
		init();
	}
	
	function startTesting() {
		if (window.performance.timing.loadEventEnd === 0) {
			window.setTimeout(startTesting, 50);
			return;
		} else {
			var funcString = "javascript:" + page_test.toString() + "; page_test(); void(0)";
			location.assign(funcString);
		}
	}
	
	
	/**
	 * 
	 */
	function handleStorageChange(storageEvent){
		if (storageEvent.key !== localStorage_key || 
				(storageEvent.key === localStorage_key && storageEvent.newValue === "")) {
			return;
		}
		
		//notify the background page that storage changed
		notifyBackgroundPage();
	}
	
	/**
	 * 
	 */
	function initializeLocalStorage(){
		localStorage[localStorage_key] = null;
		document.body.addEventListener("storage", handleStorageChange, false);
	}
	
	/**
	 * 
	 */
	function init(){
		if (test_running) {
			return;
		}
		
		test_running = true;
		initializeLocalStorage();
		startTesting();
	};
})();